package gloridifice.watersource.common.block;

import gloridifice.watersource.common.capability.WaterLevelCapability;
import gloridifice.watersource.common.tile.WaterDispenserDownTile;
import gloridifice.watersource.registry.ConfigRegistry;
import gloridifice.watersource.registry.EffectRegistry;
import gloridifice.watersource.registry.FluidRegistry;
import gloridifice.watersource.registry.TileEntityTypesRegistry;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.EffectInstance;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;

import javax.annotation.Nullable;

import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING;

public class WaterDispenserBlock extends Block {
    public static final BooleanProperty IS_UP = BooleanProperty.create("up");

    public WaterDispenserBlock(String name, Properties properties) {
        super(properties);
        this.setRegistryName(name);
        setDefaultState(getDefaultState().with(IS_UP, false).with(HORIZONTAL_FACING, Direction.EAST));
    }

    @Override
    public boolean hasTileEntity(BlockState state) {
        return true;
    }

    @Override
    protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
        builder.add(IS_UP, HORIZONTAL_FACING);
    }

    @Nullable
    @Override
    public TileEntity createTileEntity(BlockState state, IBlockReader world) {
        return state.get(IS_UP) ? TileEntityTypesRegistry.WATER_DISPENSER_UP.create() : TileEntityTypesRegistry.WATER_DISPENSER_DOWN.create();
    }

    @Override
    public void onBlockPlacedBy(World world, BlockPos blockPos, BlockState state, @Nullable LivingEntity livingEntity, ItemStack itemStack) {
        world.setBlockState(blockPos.up(), getStateForPlacement(livingEntity).with(IS_UP, true));
    }

    @Override
    public void onBlockHarvested(World world, BlockPos blockPos, BlockState state, PlayerEntity playerEntity) {
        if (state.get(IS_UP)) {
            world.setBlockState(blockPos.down(), Blocks.AIR.getDefaultState());
        } else world.setBlockState(blockPos.up(), Blocks.AIR.getDefaultState());
        super.onBlockHarvested(world, blockPos, state, playerEntity);
    }

    @Nullable
    @Override
    public BlockState getStateForPlacement(BlockItemUseContext context) {
        if (context.getWorld().isAirBlock(context.getPos().up()) && context.getPos().up().getY() < 255) {
            return getStateForPlacement(context.getPlayer());
        } else return null;
    }

    public BlockState getStateForPlacement(LivingEntity living) {
        return getDefaultState().with(HORIZONTAL_FACING, living.getHorizontalFacing().getOpposite());
    }

    @Override
    public ActionResultType onBlockActivated(BlockState state, World world, BlockPos blockPos, PlayerEntity player, Hand hand, BlockRayTraceResult result) {
        TileEntity tile = world.getTileEntity(blockPos);
        WaterLevelCapability.Data data = player.getCapability(WaterLevelCapability.PLAYER_WATER_LEVEL).orElse(null);
        IFluidHandler fluidHandler = tile.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY).orElse(null);
        ItemStack heldItem = player.getHeldItem(hand);
        if (!heldItem. isEmpty()) {
            //液体交互
            return FluidUtil.interactWithFluidHandler(player, hand, fluidHandler) ? ActionResultType.SUCCESS : ActionResultType.PASS;
        } else {
            if (player.isSneaking()) {//clear fluid
                if (fluidHandler.getFluidInTank(0).getAmount() > 0) {
                    world.playSound(player, blockPos, SoundEvents.ITEM_BUCKET_EMPTY, SoundCategory.PLAYERS, 1.0f, 1.0f);
                    fluidHandler.drain(fluidHandler.getTankCapacity(0), IFluidHandler.FluidAction.EXECUTE);
                    return ActionResultType.SUCCESS;
                }
            } else if (data.getWaterLevel() < 20 && fluidHandler.getFluidInTank(0).getAmount() >= 250) {
                Fluid fluid = fluidHandler.getFluidInTank(0).getFluid();
                if (FluidRegistry.PURIFIED_WATER.get().getFluid().equals(fluid)) {
                    data.restoreWater(5, 6);
                } else if (FluidRegistry.SOUL_WATER.get().getFluid().equals(fluid)) {
                    data.restoreWater(4, 3);
                    player.addPotionEffect(new EffectInstance(EffectRegistry.ACCOMPANYING_SOUL, 8000, 0));
                } else if (fluid.equals(Fluids.WATER)){
                    data.restoreWater(5, 0);
                    if (ConfigRegistry.THIRST_DEBUFF_DURATION.get() > -1) player.addPotionEffect(new EffectInstance(EffectRegistry.THIRST, ConfigRegistry.THIRST_DEBUFF_DURATION.get(), 0));
                } else return ActionResultType.PASS;
                fluidHandler.drain(250, IFluidHandler.FluidAction.EXECUTE);
                world.playSound(player, blockPos, SoundEvents.ENTITY_GENERIC_DRINK, SoundCategory.PLAYERS, 1.0f, 1.0f);
                return ActionResultType.SUCCESS;
            }
        }
        return ActionResultType.PASS;
    }
}
